"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.
"""

"""
Case Type   : 资源池化
Case Name   : 资源池化场景下,failover前后执行物化视图相关操作
Create At   : 2025-03-03
Owner       : zhongchengzhi
Description :
    1、查询集群状态
    2、创建表1 并插入数据
    3、创建表2 并插入数据
    4、创建增量物化视图,视图名与基表名相同
    5、创建普通视图
    6、构造主机dn故障
    7、创建增量物化视图,与普通视图同名
    8、创建增量物化视图
    9、创建增量物化视图,与已存在增量物化视图同名
    10、创建增量物化视图,视图名使用系统保留字
    11、创建普通索引
    12、创建增量物化视图,视图名与索引名相同
    13、清理环境
    14、恢复集群原始状态

Expect      :
    1、查询结果正常
    2、创建、插入数据成功
    3、创建、插入数据成功
    4、合理报错,已存在
    5、创建普通视图成功
    6、主机failover成功
    7、合理报错,已存在
    8、创建增量物化视图成功
    9、合理报错,已存在
    10、合理报错
    11、创建普通索引成功
    12、合理报错,已存在
    13、清理环境成功
    14、恢复集群原始状态成功,集群状态正常
History     :
    1、2025-03-03 创建
    2、2025-07-12 改造用例为1p1s环境可执行
"""
import os
import unittest
import time

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro

Primary_ROOTSH = CommonSH('PrimaryRoot')
Primary_SH = CommonSH('PrimaryDbUser')
Standby1_SH = CommonSH('Standby1DbUser')

@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.s1_comsh = CommonSH('Standby1DbUser')

    def test_shared_storage(self):
        text = '-----step1:查询数据库集群状态-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step2:创建表1 并插入数据;expect:成功-----'
        self.log.info(text)
        sql = f'''
                drop table if exists t_imv_0004 cascade;
                create table t_imv_0004 (c_int int, c_char char(1));
                insert into t_imv_0004 values (1, 'a');
                insert into t_imv_0004 values (2, 'b');
                insert into t_imv_0004 values (3, 'c');
                '''
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('CREATE TABLE\nINSERT 0 1\nINSERT 0 1\nINSERT 0 1', status, '执行失败' + text)

        text = '-----step3:创建表2 并插入数据;expect:成功-----'
        self.log.info(text)
        sql = f'''
                drop table if exists t_imv_0004_01 cascade;
                create table t_imv_0004_01 (c1 varchar(10));
                insert into t_imv_0004_01 values('good');
                insert into t_imv_0004_01 values('food');
                '''
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('CREATE TABLE\nINSERT 0 1\nINSERT 0 1', status, '执行失败' + text)

        text = '-----step4:创建增量物化视图,视图名与基表名相同;expect:合理报错，已存在-----'
        self.log.info(text)
        sql = f'''
                create table t_imv_0004_01 (c1 varchar(10));
                insert into t_imv_0004_01 values('good');
                insert into t_imv_0004_01 values('food');
                '''
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('ERROR:  relation "t_imv_0004_01" already exists in schema "public"', status, '执行失败' + text)

        text = '-----step5:创建普通视图;expect:成功-----'
        self.log.info(text)
        sql = f'''
                drop view if exists v_imv_0004;
                create view v_imv_0004 as select c_int from t_imv_0004 where c_int > 2;
                '''
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('CREATE VIEW', status, '执行失败' + text)

        text = '-----step6:构造主机DN故障 expect:集群failover成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_failover()
        self.log.info(stopdn)
        time.sleep(40)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        self.log.info(res1)
        self.log.info(res2)
        self.assertIn('P Down    Manually stopped', res1, '执行失败' + text)
        self.assertTrue('S Primary Normal' in res2, '执行失败' + text)

        text = '-----step7:新主节点创建增量物化视图，与普通视图同名;expect:合理报错，已存在-----'
        self.log.info(text)
        sql = f"create incremental materialized view v_imv_0004 as table t_imv_0004;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('ERROR:  relation "v_imv_0004" already exists in schema "public"', status, '执行失败' + text)

        text = '-----step8:新主节点创建增量物化视图;expect:成功-----'
        self.log.info(text)
        sql = f"create incremental materialized view imv_0004_01 as table t_imv_0004;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('CREATE MATERIALIZED VIEW', status, '执行失败' + text)

        text = '-----step9:新主节点创建增量物化视图,与已存在增量物化视图同名;expect:合理报错，已存在-----'
        self.log.info(text)
        sql = f"create incremental materialized view imv_0004_01 as table t_imv_0004_01;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('ERROR:  relation "imv_0004_01" already exists in schema "public"', status, '执行失败' + text)

        text = '-----step10:新主节点创建增量物化视图，视图名使用系统保留字;expect:合理报错-----'
        self.log.info(text)
        sql = f"create incremental materialized view user(c_char) as select c_char from t_imv_0004;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('ERROR:  syntax error at or near "user"', status, '执行失败' + text)

        text = '-----step11:新主节点创建普通索引;expect:成功-----'
        self.log.info(text)
        sql = f"create index i_imv_0004 on t_imv_0004(c_int);"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('CREATE INDEX', status, '执行失败' + text)

        text = '-----step12:新主节点创建增量物化视图,视图名与索引名相同;expect:合理报错，已存在-----'
        self.log.info(text)
        sql = f"create incremental materialized view i_imv_0004 as select c_char from t_imv_0004;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('ERROR:  relation "i_imv_0004" already exists in schema "public"', status, '执行失败' + text)

        text = '-----step13:清理环境;expect:成功-----'
        self.log.info(text)
        sql = f"drop table t_imv_0004 cascade; drop table t_imv_0004_01 cascade;"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('DROP TABLE\nDROP TABLE', status, '执行失败' + text)

    def tearDown(self):
        text = '-----step14:恢复集群初始状态;expect:成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='stop')
        self.log.info(status)
        self.assertIn('cm_ctl: stop cluster successfully.', status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='start')
        self.log.info(status)
        self.assertIn('cm_ctl: start cluster successfully.', status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(status)
        self.assertIn(self.constant.cm_switchover_success_msg, status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')